package com.ljb.demompandroidchart.mpchartutils;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.custom.LineMarkView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.ljb.demompandroidchart.R;

import java.util.ArrayList;
import java.util.List;

/**
 * MPAndroid线性图的工具类.好的代码不需要注释
 * Created by lijianbin on 2016/12/21.
 */
public class LineUtils implements OnChartValueSelectedListener {
    private String[] mColors = {"#9F6AFF", "#5EC6D3", "#F867B0", "#F8E7B8", "#56FD99D4", "#5651B6FD", "#56A0F4FF", "#56FE9A69", "#56FD9E51", "#56936CAF"};
    private static LineUtils utils;
    private LineChart mChart;
    private int count;
    private boolean toggleValues = false;
    private Boolean isHightEnalbe = true;
    private String mColor = "#69758f";
    private XAxis xAxis;
    private float labelAngle = 0f;
    private Context mContext;
    private boolean isShowLegned;

    private LineUtils(Context context) {
        mContext = context;
    }

    /**
     * 获取单例工具类对象
     */
    public static LineUtils getInstance(Context context) {

//        if (utils == null)
        utils = new LineUtils(context);

        return utils;
    }

    /**
     * 初始化chart
     */
    public LineUtils initChart(LineChart chart) {
        mChart = chart;
//        mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
        mChart.setDrawGridBackground(false);
        mChart.getDescription().setEnabled(false);
        mChart.setDrawBorders(false);

        mChart.setExtraOffsets(0, 20, 0, 10);

        // enable touch gestures
        mChart.setTouchEnabled(true);

        // enable scaling and dragging
        mChart.setDragEnabled(false);
        mChart.setScaleEnabled(false);

        // if disabled, scaling can be done on x- and y-axis separately
        mChart.setPinchZoom(false);

        LineMarkView mv = new LineMarkView(mContext, R.layout.line_marker_view);
        mv.setChartView(mChart); // For bounds control
        mChart.setMarker(mv); // Set the marker to the chart

        initAxis();

        return this;
    }

    private void initAxis() {
        //X轴
        xAxis = mChart.getXAxis();
        xAxis.setTextSize(11f);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextColor(rgb(mColor));
        xAxis.setDrawGridLines(false);
        xAxis.setDrawAxisLine(true);
        xAxis.setGranularityEnabled(true);
        xAxis.setAxisLineWidth(2f);
        xAxis.setAxisLineColor(rgb(mColor));
        xAxis.setLabelRotationAngle(labelAngle);//设置x轴标签的角度

        //Y轴左边
        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.setTextColor(rgb(mColor));
//        leftAxis.setAxisMaximum(200f);
        leftAxis.setAxisMinimum(0f);
        leftAxis.setDrawGridLines(false);
        leftAxis.setGranularityEnabled(true);
        leftAxis.setAxisLineWidth(2f);
        leftAxis.setAxisLineColor(rgb(mColor));
        //Y轴右侧
        YAxis rightAxis = mChart.getAxisRight();
        rightAxis.setEnabled(false);
    }

    /**
     * 设置图例
     */
    public LineUtils setLegend(boolean isEnable) {
        isShowLegned = isEnable;
        if (mChart != null) {
            Legend l = mChart.getLegend();
            if (isEnable) {
                l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
                l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
                l.setOrientation(Legend.LegendOrientation.VERTICAL);
                l.setDrawInside(true);
            }
            l.setEnabled(isEnable);
        }
        return this;
    }

    public LineUtils initLabelAngle(float angle) {
        labelAngle = angle;
        return this;
    }

    public LineUtils toggleValues(Boolean isEnable) {
        toggleValues = isEnable;
        return this;
    }

    public LineUtils highlightEnable(Boolean isEnable) {
        isHightEnalbe = isEnable;
        return this;
    }

    public LineUtils initAxisColor(String color) {
        mColor = color;
        return this;
    }

    public LineUtils initLineColors(String[] colors) {
        mColors = colors;
        return this;
    }

    public void show() {
        if (mChart != null)
            mChart.invalidate();
    }

    /**
     * 初始化X轴数据
     */
    public LineUtils setXData(String[] values) {
        xAxis.setValueFormatter(new IndexAxisValueFormatter(values));
        return this;
    }

    /**
     * 设置Y轴数据
     */
    public LineUtils setYData(float[][] values, String[] labels) {
        count = values.length;
        if (labels == null) {
            labels = new String[1];
            labels[0] = "";
        }
        if (count != labels.length) {
            throw new IllegalArgumentException("折线图的数据条数必须和折线图名称数组一样多");
        }
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        for (int j = 0; j < count; j++) {//总共有几条线
            ArrayList<Entry> yValues = new ArrayList<>();//每一条线上的数据
            for (int i = 0; i < values[0].length; i++) {
                yValues.add(new Entry(i, values[j][i]));
            }
            LineDataSet dataSet = new LineDataSet(yValues, labels[j]);
            if (mColors.length >= count) {
                initColor(mColors[j], dataSet);
            } else {
                throw new IllegalArgumentException("颜色集合必须比饼状图的块数多");
            }
            dataSet.setLineWidth(2.5f);
            dataSet.setCircleRadius(4f);
            dataSet.setDrawValues(toggleValues);
            dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
//            dataSet.setDrawCircles(false);
            dataSet.setDrawCircleHole(false);
            dataSet.setHighlightEnabled(isHightEnalbe);
            dataSet.setDrawHighlightIndicators(isHightEnalbe);
//            dataSet.setHighLightColor(Color.BLACK);
            dataSets.add(dataSet);
        }

        LineData data = new LineData(dataSets);

        mChart.setData(data);

        return this;
    }

    private void initColor(String mColor, LineDataSet d) {
        int color = rgb(mColor);
        d.setColor(color);
        d.setCircleColor(color);
    }

    private int rgb(String hex) {
        int color = (int) Long.parseLong(hex.replace("#", ""), 16);
        int r = (color >> 16) & 0xFF;
        int g = (color >> 8) & 0xFF;
        int b = (color >> 0) & 0xFF;
        return Color.rgb(r, g, b);
    }

    @Override
    public void onValueSelected(Entry e, Highlight h) {
        Log.i("Entry selected", e.toString());
        Log.i("LOWHIGH", "low: " + mChart.getLowestVisibleX() + ", high: " + mChart.getHighestVisibleX());
        Log.i("MIN MAX", "xmin: " + mChart.getXChartMin() + ", xmax: " + mChart.getXChartMax() + ", ymin: " + mChart.getYChartMin() + ", ymax: " + mChart.getYChartMax());

        if (isShowLegned) {
            mChart.getLegend().setEnabled(false);
        }
        if (mListener != null)
            mListener.onValueSelected(e, h);
    }

    @Override
    public void onNothingSelected() {
        Log.i("Nothing selected", "Nothing selected.");
        if (isShowLegned) {
            mChart.getLegend().setEnabled(true);
        }
//        if (mListener != null)
//            mListener.onNothingSelected();
    }

    private void setDrawValue(Boolean isDrawValue) {
        List<ILineDataSet> sets = mChart.getData().getDataSets();
        for (ILineDataSet iSet : sets) {
            LineDataSet set = (LineDataSet) iSet;
            set.setDrawValues(isDrawValue);
        }
        mChart.invalidate();
    }

    private OnValueTouchListener mListener;

    public LineUtils setOnValueTouchListener(OnValueTouchListener listener) {
        if (listener != null)
            mListener = listener;
        return this;
    }

}
